home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / mozilla-firefox / include / layout / nsBidi.h next >
Text File  |  2006-05-08  |  42KB  |  1,061 lines

  1. /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * ***** BEGIN LICENSE BLOCK *****
  4.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  5.  *
  6.  * The contents of this file are subject to the Mozilla Public License Version
  7.  * 1.1 (the "License"); you may not use this file except in compliance with
  8.  * the License. You may obtain a copy of the License at
  9.  * http://www.mozilla.org/MPL/
  10.  *
  11.  * Software distributed under the License is distributed on an "AS IS" basis,
  12.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  13.  * for the specific language governing rights and limitations under the
  14.  * License.
  15.  *
  16.  * The Original Code is mozilla.org code.
  17.  *
  18.  * The Initial Developer of the Original Code is
  19.  * IBM Corporation.
  20.  * Portions created by the Initial Developer are Copyright (C) 2000
  21.  * the Initial Developer. All Rights Reserved.
  22.  *
  23.  * Contributor(s):
  24.  *   Simon Montagu
  25.  *
  26.  * Alternatively, the contents of this file may be used under the terms of
  27.  * either of the GNU General Public License Version 2 or later (the "GPL"),
  28.  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  29.  * in which case the provisions of the GPL or the LGPL are applicable instead
  30.  * of those above. If you wish to allow use of your version of this file only
  31.  * under the terms of either the GPL or the LGPL, and not to allow others to
  32.  * use your version of this file under the terms of the MPL, indicate your
  33.  * decision by deleting the provisions above and replace them with the notice
  34.  * and other provisions required by the GPL or the LGPL. If you do not delete
  35.  * the provisions above, a recipient may use your version of this file under
  36.  * the terms of any one of the MPL, the GPL or the LGPL.
  37.  *
  38.  * ***** END LICENSE BLOCK ***** */
  39.  
  40. #ifndef nsBidi_h__
  41. #define nsBidi_h__
  42.  
  43. #include "nsCOMPtr.h"
  44. #include "nsString.h"
  45.  
  46. // Bidi reordering engine from ICU
  47. /*
  48.  * javadoc-style comments are intended to be transformed into HTML
  49.  * using DOC++ - see
  50.  * http://www.zib.de/Visual/software/doc++/index.html .
  51.  *
  52.  * The HTML documentation is created with
  53.  *  doc++ -H nsIBidi.h
  54.  */
  55.  
  56. /**
  57.  * @mainpage BIDI algorithm for Mozilla (from ICU)
  58.  *
  59.  * <h2>BIDI algorithm for Mozilla</h2>
  60.  *
  61.  * This is an implementation of the Unicode Bidirectional algorithm.
  62.  * The algorithm is defined in the
  63.  * <a href="http://www.unicode.org/unicode/reports/tr9/">Unicode Technical Report 9</a>,
  64.  * version 5, also described in The Unicode Standard, Version 3.0 .<p>
  65.  *
  66.  * <h3>General remarks about the API:</h3>
  67.  *
  68.  * The <quote>limit</quote> of a sequence of characters is the position just after their
  69.  * last character, i.e., one more than that position.<p>
  70.  *
  71.  * Some of the API functions provide access to <quote>runs</quote>.
  72.  * Such a <quote>run</quote> is defined as a sequence of characters
  73.  * that are at the same embedding level
  74.  * after performing the BIDI algorithm.<p>
  75.  *
  76.  * @author Markus W. Scherer. Ported to Mozilla by Simon Montagu
  77.  * @version 1.0
  78.  */
  79.  
  80. /**
  81.  * nsBidiLevel is the type of the level values in this
  82.  * Bidi implementation.
  83.  * It holds an embedding level and indicates the visual direction
  84.  * by its bit 0 (even/odd value).<p>
  85.  *
  86.  * It can also hold non-level values for the
  87.  * <code>aParaLevel</code> and <code>aEmbeddingLevels</code>
  88.  * arguments of <code>SetPara</code>; there:
  89.  * <ul>
  90.  * <li>bit 7 of an <code>aEmbeddingLevels[]</code>
  91.  * value indicates whether the using application is
  92.  * specifying the level of a character to <i>override</i> whatever the
  93.  * Bidi implementation would resolve it to.</li>
  94.  * <li><code>aParaLevel</code> can be set to the
  95.  * pseudo-level values <code>NSBIDI_DEFAULT_LTR</code>
  96.  * and <code>NSBIDI_DEFAULT_RTL</code>.</li></ul>
  97.  *
  98.  * @see nsIBidi::SetPara
  99.  *
  100.  * <p>The related constants are not real, valid level values.
  101.  * <code>NSBIDI_DEFAULT_XXX</code> can be used to specify
  102.  * a default for the paragraph level for
  103.  * when the <code>SetPara</code> function
  104.  * shall determine it but there is no
  105.  * strongly typed character in the input.<p>
  106.  *
  107.  * Note that the value for <code>NSBIDI_DEFAULT_LTR</code> is even
  108.  * and the one for <code>NSBIDI_DEFAULT_RTL</code> is odd,
  109.  * just like with normal LTR and RTL level values -
  110.  * these special values are designed that way. Also, the implementation
  111.  * assumes that NSBIDI_MAX_EXPLICIT_LEVEL is odd.
  112.  *
  113.  * @see NSBIDI_DEFAULT_LTR
  114.  * @see NSBIDI_DEFAULT_RTL
  115.  * @see NSBIDI_LEVEL_OVERRIDE
  116.  * @see NSBIDI_MAX_EXPLICIT_LEVEL
  117.  */
  118. typedef PRUint8 nsBidiLevel;
  119.  
  120. /** Paragraph level setting.
  121.  *  If there is no strong character, then set the paragraph level to 0 (left-to-right).
  122.  */
  123. #define NSBIDI_DEFAULT_LTR 0xfe
  124.  
  125. /** Paragraph level setting.
  126.  *  If there is no strong character, then set the paragraph level to 1 (right-to-left).
  127.  */
  128. #define NSBIDI_DEFAULT_RTL 0xff
  129.  
  130. /**
  131.  * Maximum explicit embedding level.
  132.  * (The maximum resolved level can be up to <code>NSBIDI_MAX_EXPLICIT_LEVEL+1</code>).
  133.  *
  134.  */
  135. #define NSBIDI_MAX_EXPLICIT_LEVEL 61
  136.  
  137. /** Bit flag for level input. 
  138.  *  Overrides directional properties. 
  139.  */
  140. #define NSBIDI_LEVEL_OVERRIDE 0x80
  141.  
  142. /**
  143.  * <code>nsBidiDirection</code> values indicate the text direction.
  144.  */
  145. enum nsBidiDirection {
  146.   /** All left-to-right text This is a 0 value. */
  147.   NSBIDI_LTR,
  148.   /** All right-to-left text This is a 1 value. */
  149.   NSBIDI_RTL,
  150.   /** Mixed-directional text. */
  151.   NSBIDI_MIXED
  152. };
  153.  
  154. typedef enum nsBidiDirection nsBidiDirection;
  155.  
  156. /* miscellaneous definitions ------------------------------------------------ */
  157.  
  158.    /**
  159.     *  Read ftp://ftp.unicode.org/Public/UNIDATA/ReadMe-Latest.txt
  160.     *  section BIDIRECTIONAL PROPERTIES
  161.     *  for the detailed definition of the following categories
  162.     *
  163.     *  The values here must match the equivalents in %map in
  164.     * mozilla/intl/unicharutil/tools/genbidicattable.pl
  165.     */
  166.  
  167. typedef enum {
  168.   eBidiCat_Undefined,
  169.   eBidiCat_L,          /* Left-to-Right               */
  170.   eBidiCat_R,          /* Right-to-Left               */
  171.   eBidiCat_AL,         /* Right-to-Left Arabic        */
  172.   eBidiCat_AN,         /* Arabic Number               */
  173.   eBidiCat_EN,         /* European Number             */
  174.   eBidiCat_ES,         /* European Number Separator   */
  175.   eBidiCat_ET,         /* European Number Terminator  */
  176.   eBidiCat_CS,         /* Common Number Separator     */
  177.   eBidiCat_ON,         /* Other Neutrals              */
  178.   eBidiCat_NSM,        /* Non-Spacing Mark            */
  179.   eBidiCat_BN,         /* Boundary Neutral            */
  180.   eBidiCat_B,          /* Paragraph Separator         */
  181.   eBidiCat_S,          /* Segment Separator           */
  182.   eBidiCat_WS,         /* Whitespace                  */
  183.   eBidiCat_CC = 0xf,   /* Control Code                */
  184.                        /* (internal use only - will never be outputed) */
  185.   eBidiCat_LRE = 0x2a, /* Left-to-Right Embedding     */
  186.   eBidiCat_RLE = 0x2b, /* Right-to-Left Embedding     */
  187.   eBidiCat_PDF = 0x2c, /* Pop Directional Formatting  */
  188.   eBidiCat_LRO = 0x2d, /* Left-to-Right Override      */
  189.   eBidiCat_RLO = 0x2e  /* Right-to-Left Override      */
  190. } eBidiCategory;
  191.  
  192. enum nsCharType   { 
  193.   eCharType_LeftToRight              = 0, 
  194.   eCharType_RightToLeft              = 1, 
  195.   eCharType_EuropeanNumber           = 2,
  196.   eCharType_EuropeanNumberSeparator  = 3,
  197.   eCharType_EuropeanNumberTerminator = 4,
  198.   eCharType_ArabicNumber             = 5,
  199.   eCharType_CommonNumberSeparator    = 6,
  200.   eCharType_BlockSeparator           = 7,
  201.   eCharType_SegmentSeparator         = 8,
  202.   eCharType_WhiteSpaceNeutral        = 9, 
  203.   eCharType_OtherNeutral             = 10, 
  204.   eCharType_LeftToRightEmbedding     = 11,
  205.   eCharType_LeftToRightOverride      = 12,
  206.   eCharType_RightToLeftArabic        = 13,
  207.   eCharType_RightToLeftEmbedding     = 14,
  208.   eCharType_RightToLeftOverride      = 15,
  209.   eCharType_PopDirectionalFormat     = 16,
  210.   eCharType_DirNonSpacingMark        = 17,
  211.   eCharType_BoundaryNeutral          = 18,
  212.   eCharType_CharTypeCount
  213. };
  214.  
  215. /**
  216.  * This specifies the language directional property of a character set.
  217.  */
  218. typedef enum nsCharType nsCharType;
  219.  
  220. /**
  221.  * definitions of bidirection character types by category
  222.  */
  223.  
  224. #define CHARTYPE_IS_RTL(val) ( ( (val) == eCharType_RightToLeft) || ( (val) == eCharType_RightToLeftArabic) )
  225.  
  226. #define CHARTYPE_IS_WEAK(val) ( ( (val) == eCharType_EuropeanNumberSeparator)    \
  227.                            || ( (val) == eCharType_EuropeanNumberTerminator) \
  228.                            || ( ( (val) > eCharType_ArabicNumber) && ( (val) != eCharType_RightToLeftArabic) ) )
  229.  
  230. /** option flags for WriteReverse() */
  231. /**
  232.  * option bit for WriteReverse():
  233.  * keep combining characters after their base characters in RTL runs
  234.  *
  235.  * @see WriteReverse
  236.  */
  237. #define NSBIDI_KEEP_BASE_COMBINING       1
  238.  
  239. /**
  240.  * option bit for WriteReverse():
  241.  * replace characters with the "mirrored" property in RTL runs
  242.  * by their mirror-image mappings
  243.  *
  244.  * @see WriteReverse
  245.  */
  246. #define NSBIDI_DO_MIRRORING              2
  247.  
  248. /**
  249.  * option bit for WriteReverse():
  250.  * remove Bidi control characters
  251.  *
  252.  * @see WriteReverse
  253.  */
  254. #define NSBIDI_REMOVE_BIDI_CONTROLS      8
  255.  
  256. /* helper macros for each allocated array member */
  257. #define GETDIRPROPSMEMORY(length) \
  258.                                   GetMemory((void **)&mDirPropsMemory, &mDirPropsSize, \
  259.                                   mMayAllocateText, (length))
  260.  
  261. #define GETLEVELSMEMORY(length) \
  262.                                 GetMemory((void **)&mLevelsMemory, &mLevelsSize, \
  263.                                 mMayAllocateText, (length))
  264.  
  265. #define GETRUNSMEMORY(length) \
  266.                               GetMemory((void **)&mRunsMemory, &mRunsSize, \
  267.                               mMayAllocateRuns, (length)*sizeof(Run))
  268.  
  269. /* additional macros used by constructor - always allow allocation */
  270. #define GETINITIALDIRPROPSMEMORY(length) \
  271.                                          GetMemory((void **)&mDirPropsMemory, &mDirPropsSize, \
  272.                                          PR_TRUE, (length))
  273.  
  274. #define GETINITIALLEVELSMEMORY(length) \
  275.                                        GetMemory((void **)&mLevelsMemory, &mLevelsSize, \
  276.                                        PR_TRUE, (length))
  277.  
  278. #define GETINITIALRUNSMEMORY(length) \
  279.                                      GetMemory((void **)&mRunsMemory, &mRunsSize, \
  280.                                      PR_TRUE, (length)*sizeof(Run))
  281.  
  282. /*
  283.  * Sometimes, bit values are more appropriate
  284.  * to deal with directionality properties.
  285.  * Abbreviations in these macro names refer to names
  286.  * used in the Bidi algorithm.
  287.  */
  288. typedef PRUint8 DirProp;
  289.  
  290. #define DIRPROP_FLAG(dir) (1UL<<(dir))
  291.  
  292. /* special flag for multiple runs from explicit embedding codes */
  293. #define DIRPROP_FLAG_MULTI_RUNS (1UL<<31)
  294.  
  295. /* are there any characters that are LTR or RTL? */
  296. #define MASK_LTR (DIRPROP_FLAG(L)|DIRPROP_FLAG(EN)|DIRPROP_FLAG(AN)|DIRPROP_FLAG(LRE)|DIRPROP_FLAG(LRO))
  297. #define MASK_RTL (DIRPROP_FLAG(R)|DIRPROP_FLAG(AL)|DIRPROP_FLAG(RLE)|DIRPROP_FLAG(RLO))
  298.  
  299. /* explicit embedding codes */
  300. #define MASK_LRX (DIRPROP_FLAG(LRE)|DIRPROP_FLAG(LRO))
  301. #define MASK_RLX (DIRPROP_FLAG(RLE)|DIRPROP_FLAG(RLO))
  302. #define MASK_OVERRIDE (DIRPROP_FLAG(LRO)|DIRPROP_FLAG(RLO))
  303.  
  304. #define MASK_EXPLICIT (MASK_LRX|MASK_RLX|DIRPROP_FLAG(PDF))
  305. #define MASK_BN_EXPLICIT (DIRPROP_FLAG(BN)|MASK_EXPLICIT)
  306.  
  307. /* paragraph and segment separators */
  308. #define MASK_B_S (DIRPROP_FLAG(B)|DIRPROP_FLAG(S))
  309.  
  310. /* all types that are counted as White Space or Neutral in some steps */
  311. #define MASK_WS (MASK_B_S|DIRPROP_FLAG(WS)|MASK_BN_EXPLICIT)
  312. #define MASK_N (DIRPROP_FLAG(O_N)|MASK_WS)
  313.  
  314. /* all types that are included in a sequence of European Terminators for (W5) */
  315. #define MASK_ET_NSM_BN (DIRPROP_FLAG(ET)|DIRPROP_FLAG(NSM)|MASK_BN_EXPLICIT)
  316.  
  317. /* types that are neutrals or could becomes neutrals in (Wn) */
  318. #define MASK_POSSIBLE_N (DIRPROP_FLAG(CS)|DIRPROP_FLAG(ES)|DIRPROP_FLAG(ET)|MASK_N)
  319.  
  320. /*
  321.  * These types may be changed to "e",
  322.  * the embedding type (L or R) of the run,
  323.  * in the Bidi algorithm (N2)
  324.  */
  325. #define MASK_EMBEDDING (DIRPROP_FLAG(NSM)|MASK_POSSIBLE_N)
  326.  
  327. /* the dirProp's L and R are defined to 0 and 1 values in nsCharType */
  328. #define GET_LR_FROM_LEVEL(level) ((DirProp)((level)&1))
  329.  
  330. #define IS_DEFAULT_LEVEL(level) (((level)&0xfe)==0xfe)
  331.  
  332. /* handle surrogate pairs --------------------------------------------------- */
  333.  
  334. #define IS_FIRST_SURROGATE(uchar) (((uchar)&0xfc00)==0xd800)
  335. #define IS_SECOND_SURROGATE(uchar) (((uchar)&0xfc00)==0xdc00)
  336.  
  337. /* get the UTF-32 value directly from the surrogate pseudo-characters */
  338. #define SURROGATE_OFFSET ((0xd800<<10UL)+0xdc00-0x10000)
  339. #define GET_UTF_32(first, second) (((first)<<10UL)+(second)-SURROGATE_OFFSET)
  340.  
  341.  
  342. #define UTF_ERROR_VALUE 0xffff
  343. /* definitions with forward iteration --------------------------------------- */
  344.  
  345. /*
  346.  * all the macros that go forward assume that
  347.  * the initial offset is 0<=i<length;
  348.  * they update the offset
  349.  */
  350.  
  351. /* fast versions, no error-checking */
  352.  
  353. #define UTF16_APPEND_CHAR_UNSAFE(s, i, c){ \
  354.                                          if((PRUint32)(c)<=0xffff) { \
  355.                                          (s)[(i)++]=(PRUnichar)(c); \
  356.                                          } else { \
  357.                                          (s)[(i)++]=(PRUnichar)((c)>>10)+0xd7c0; \
  358.                                          (s)[(i)++]=(PRUnichar)(c)&0x3ff|0xdc00; \
  359.                                          } \
  360. }
  361.  
  362. /* safe versions with error-checking and optional regularity-checking */
  363.  
  364. #define UTF16_APPEND_CHAR_SAFE(s, i, length, c) { \
  365.                                                 if((PRUInt32)(c)<=0xffff) { \
  366.                                                 (s)[(i)++]=(PRUnichar)(c); \
  367.                                                 } else if((PRUInt32)(c)<=0x10ffff) { \
  368.                                                 if((i)+1<(length)) { \
  369.                                                 (s)[(i)++]=(PRUnichar)((c)>>10)+0xd7c0; \
  370.                                                 (s)[(i)++]=(PRUnichar)(c)&0x3ff|0xdc00; \
  371.                                                 } else /* not enough space */ { \
  372.                                                 (s)[(i)++]=UTF_ERROR_VALUE; \
  373.                                                 } \
  374.                                                 } else /* c>0x10ffff, write error value */ { \
  375.                                                 (s)[(i)++]=UTF_ERROR_VALUE; \
  376.                                                 } \
  377. }
  378.  
  379. /* definitions with backward iteration -------------------------------------- */
  380.  
  381. /*
  382.  * all the macros that go backward assume that
  383.  * the valid buffer range starts at offset 0
  384.  * and that the initial offset is 0<i<=length;
  385.  * they update the offset
  386.  */
  387.  
  388. /* fast versions, no error-checking */
  389.  
  390. /*
  391.  * Get a single code point from an offset that points behind the last
  392.  * of the code units that belong to that code point.
  393.  * Assume 0<=i<length.
  394.  */
  395. #define UTF16_PREV_CHAR_UNSAFE(s, i, c) { \
  396.                                         (c)=(s)[--(i)]; \
  397.                                         if(IS_SECOND_SURROGATE(c)) { \
  398.                                         (c)=GET_UTF_32((s)[--(i)], (c)); \
  399.                                         } \
  400. }
  401.  
  402. #define UTF16_BACK_1_UNSAFE(s, i) { \
  403.                                   if(IS_SECOND_SURROGATE((s)[--(i)])) { \
  404.                                   --(i); \
  405.                                   } \
  406. }
  407.  
  408. #define UTF16_BACK_N_UNSAFE(s, i, n) { \
  409.                                      PRInt32 __N=(n); \
  410.                                      while(__N>0) { \
  411.                                      UTF16_BACK_1_UNSAFE(s, i); \
  412.                                      --__N; \
  413.                                      } \
  414. }
  415.  
  416. /* safe versions with error-checking and optional regularity-checking */
  417.  
  418. #define UTF16_PREV_CHAR_SAFE(s, start, i, c, strict) { \
  419.                                                      (c)=(s)[--(i)]; \
  420.                                                      if(IS_SECOND_SURROGATE(c)) { \
  421.                                                      PRUnichar __c2; \
  422.                                                      if((i)>(start) && IS_FIRST_SURROGATE(__c2=(s)[(i)-1])) { \
  423.                                                      --(i); \
  424.                                                      (c)=GET_UTF_32(__c2, (c)); \
  425.       /* strict: ((c)&0xfffe)==0xfffe is caught by UTF_IS_ERROR() */ \
  426.                                                      } else if(strict) {\
  427.       /* unmatched second surrogate */ \
  428.                                                      (c)=UTF_ERROR_VALUE; \
  429.                                                      } \
  430.                                                      } else if(strict && IS_FIRST_SURROGATE(c)) { \
  431.       /* unmatched first surrogate */ \
  432.                                                      (c)=UTF_ERROR_VALUE; \
  433.   /* else strict: (c)==0xfffe is caught by UTF_IS_ERROR() */ \
  434.                                                      } \
  435. }
  436.  
  437. #define UTF16_BACK_1_SAFE(s, start, i) { \
  438.                                        if(IS_SECOND_SURROGATE((s)[--(i)]) && (i)>(start) && IS_FIRST_SURROGATE((s)[(i)-1])) { \
  439.                                        --(i); \
  440.                                        } \
  441. }
  442.  
  443. #define UTF16_BACK_N_SAFE(s, start, i, n) { \
  444.                                           PRInt32 __N=(n); \
  445.                                           while(__N>0 && (i)>(start)) { \
  446.                                           UTF16_BACK_1_SAFE(s, start, i); \
  447.                                           --__N; \
  448.                                           } \
  449. }
  450.  
  451. #define UTF_PREV_CHAR_UNSAFE(s, i, c)                UTF16_PREV_CHAR_UNSAFE(s, i, c)
  452. #define UTF_PREV_CHAR_SAFE(s, start, i, c, strict)   UTF16_PREV_CHAR_SAFE(s, start, i, c, strict)
  453. #define UTF_BACK_1_UNSAFE(s, i)                      UTF16_BACK_1_UNSAFE(s, i)
  454. #define UTF_BACK_1_SAFE(s, start, i)                 UTF16_BACK_1_SAFE(s, start, i)
  455. #define UTF_BACK_N_UNSAFE(s, i, n)                   UTF16_BACK_N_UNSAFE(s, i, n)
  456. #define UTF_BACK_N_SAFE(s, start, i, n)              UTF16_BACK_N_SAFE(s, start, i, n)
  457. #define UTF_APPEND_CHAR_UNSAFE(s, i, c)              UTF16_APPEND_CHAR_UNSAFE(s, i, c)
  458. #define UTF_APPEND_CHAR_SAFE(s, i, length, c)        UTF16_APPEND_CHAR_SAFE(s, i, length, c)
  459.  
  460. #define UTF_PREV_CHAR(s, start, i, c)                UTF_PREV_CHAR_SAFE(s, start, i, c, PR_FALSE)
  461. #define UTF_BACK_1(s, start, i)                      UTF_BACK_1_SAFE(s, start, i)
  462. #define UTF_BACK_N(s, start, i, n)                   UTF_BACK_N_SAFE(s, start, i, n)
  463. #define UTF_APPEND_CHAR(s, i, length, c)             UTF_APPEND_CHAR_SAFE(s, i, length, c)
  464.  
  465. /* Run structure for reordering --------------------------------------------- */
  466.  
  467. typedef struct Run {
  468.   PRInt32 logicalStart,  /* first character of the run; b31 indicates even/odd level */
  469.   visualLimit;  /* last visual position of the run +1 */
  470. } Run;
  471.  
  472. /* in a Run, logicalStart will get this bit set if the run level is odd */
  473. #define INDEX_ODD_BIT (1UL<<31)
  474.  
  475. #define MAKE_INDEX_ODD_PAIR(index, level) (index|((PRUint32)level<<31))
  476. #define ADD_ODD_BIT_FROM_LEVEL(x, level)  ((x)|=((PRUint32)level<<31))
  477. #define REMOVE_ODD_BIT(x)          ((x)&=~INDEX_ODD_BIT)
  478.  
  479. #define GET_INDEX(x)   (x&~INDEX_ODD_BIT)
  480. #define GET_ODD_BIT(x) ((PRUint32)x>>31)
  481. #define IS_ODD_RUN(x)  ((x&INDEX_ODD_BIT)!=0)
  482. #define IS_EVEN_RUN(x) ((x&INDEX_ODD_BIT)==0)
  483.  
  484. typedef PRUint32 Flags;
  485.  
  486. /**
  487.  * This class holds information about a paragraph of text
  488.  * with Bidi-algorithm-related details, or about one line of
  489.  * such a paragraph.<p>
  490.  * Reordering can be done on a line, or on a paragraph which is
  491.  * then interpreted as one single line.<p>
  492.  *
  493.  * On construction, the class is initially empty. It is assigned
  494.  * the Bidi properties of a paragraph by <code>SetPara</code>
  495.  * or the Bidi properties of a line of a paragraph by
  496.  * <code>SetLine</code>.<p>
  497.  * A Bidi class can be reused for as long as it is not deallocated
  498.  * by calling its destructor.<p>
  499.  * <code>SetPara</code> will allocate additional memory for
  500.  * internal structures as necessary.
  501.  */
  502. class nsBidi
  503. {
  504. public: 
  505.   /** @brief Default constructor.
  506.    * 
  507.    * The nsBidi object is initially empty. It is assigned
  508.    * the Bidi properties of a paragraph by <code>SetPara()</code>
  509.    * or the Bidi properties of a line of a paragraph by
  510.    * <code>GetLine()</code>.<p>
  511.    * This object can be reused for as long as it is not destroyed.<p>
  512.    * <code>SetPara()</code> will allocate additional memory for
  513.    * internal structures as necessary.
  514.    *
  515.    */
  516.   nsBidi();
  517.  
  518.   /** @brief Preallocating constructor
  519.    * Allocate an <code>nsBidi</code>
  520.    * object with preallocated memory for internal structures.   This
  521.    * constructor provides an <code>nsBidi</code> object like
  522.    * the default constructor, but it also
  523.    * preallocates memory for internal structures according to the sizings
  524.    * supplied by the caller.<p> Subsequent functions will not allocate
  525.    * any more memory, and are thus guaranteed not to fail because of lack
  526.    * of memory.<p> The preallocation can be limited to some of the
  527.    * internal memory by setting some values to 0 here. That means that
  528.    * if, e.g., <code>aMaxRunCount</code> cannot be reasonably
  529.    * predetermined and should not be set to <code>aMaxLength</code> (the
  530.    * only failproof value) to avoid wasting memory, then
  531.    * <code>aMaxRunCount</code> could be set to 0 here and the internal
  532.    * structures that are associated with it will be allocated on demand,
  533.    * just like with the default constructor.
  534.    *
  535.    * If sufficient memory could not be allocated, no exception is thrown.
  536.    * Test whether mDirPropsSize == aMaxLength and/or mRunsSize == aMaxRunCount.
  537.    *
  538.    * @param aMaxLength is the maximum paragraph or line length that internal memory
  539.    *      will be preallocated for. An attempt to associate this object with a
  540.    *      longer text will fail, unless this value is 0, which leaves the allocation
  541.    *      up to the implementation.
  542.    *
  543.    * @param aMaxRunCount is the maximum anticipated number of same-level runs
  544.    *      that internal memory will be preallocated for. An attempt to access
  545.    *      visual runs on an object that was not preallocated for as many runs
  546.    *      as the text was actually resolved to will fail,
  547.    *      unless this value is 0, which leaves the allocation up to the implementation.<p>
  548.    *      The number of runs depends on the actual text and maybe anywhere between
  549.    *      1 and <code>aMaxLength</code>. It is typically small.<p>
  550.    */
  551.   nsBidi(PRUint32 aMaxLength, PRUint32 aMaxRunCount);
  552.  
  553.   /** @brief Destructor. */
  554.   virtual ~nsBidi();
  555.  
  556.  
  557.   /**
  558.    * Perform the Unicode Bidi algorithm. It is defined in the
  559.    * <a href="http://www.unicode.org/unicode/reports/tr9/">Unicode Technical Report 9</a>,
  560.    * version 5,
  561.    * also described in The Unicode Standard, Version 3.0 .<p>
  562.    *
  563.    * This function takes a single plain text paragraph with or without
  564.    * externally specified embedding levels from <quote>styled</quote> text
  565.    * and computes the left-right-directionality of each character.<p>
  566.    *
  567.    * If the entire paragraph consists of text of only one direction, then
  568.    * the function may not perform all the steps described by the algorithm,
  569.    * i.e., some levels may not be the same as if all steps were performed.
  570.    * This is not relevant for unidirectional text.<br>
  571.    * For example, in pure LTR text with numbers the numbers would get
  572.    * a resolved level of 2 higher than the surrounding text according to
  573.    * the algorithm. This implementation may set all resolved levels to
  574.    * the same value in such a case.<p>
  575.    *
  576.    * The text must be externally split into separate paragraphs (rule P1).
  577.    * Paragraph separators (B) should appear at most at the very end.
  578.    *
  579.    * @param aText is a pointer to the single-paragraph text that the
  580.    *      Bidi algorithm will be performed on
  581.    *      (step (P1) of the algorithm is performed externally).
  582.    *      <strong>The text must be (at least) <code>aLength</code> long.</strong>
  583.    *
  584.    * @param aLength is the length of the text; if <code>aLength==-1</code> then
  585.    *      the text must be zero-terminated.
  586.    *
  587.    * @param aParaLevel specifies the default level for the paragraph;
  588.    *      it is typically 0 (LTR) or 1 (RTL).
  589.    *      If the function shall determine the paragraph level from the text,
  590.    *      then <code>aParaLevel</code> can be set to
  591.    *      either <code>NSBIDI_DEFAULT_LTR</code>
  592.    *      or <code>NSBIDI_DEFAULT_RTL</code>;
  593.    *      if there is no strongly typed character, then
  594.    *      the desired default is used (0 for LTR or 1 for RTL).
  595.    *      Any other value between 0 and <code>NSBIDI_MAX_EXPLICIT_LEVEL</code> is also valid,
  596.    *      with odd levels indicating RTL.
  597.    *
  598.    * @param aEmbeddingLevels (in) may be used to preset the embedding and override levels,
  599.    *      ignoring characters like LRE and PDF in the text.
  600.    *      A level overrides the directional property of its corresponding
  601.    *      (same index) character if the level has the
  602.    *      <code>NSBIDI_LEVEL_OVERRIDE</code> bit set.<p>
  603.    *      Except for that bit, it must be
  604.    *      <code>aParaLevel<=aEmbeddingLevels[]<=NSBIDI_MAX_EXPLICIT_LEVEL</code>.<p>
  605.    *      <strong>Caution: </strong>A copy of this pointer, not of the levels,
  606.    *      will be stored in the <code>nsBidi</code> object;
  607.    *      the <code>aEmbeddingLevels</code> array must not be
  608.    *      deallocated before the <code>nsBidi</code> object is destroyed or reused,
  609.    *      and the <code>aEmbeddingLevels</code>
  610.    *      should not be modified to avoid unexpected results on subsequent Bidi operations.
  611.    *      However, the <code>SetPara</code> and
  612.    *      <code>SetLine</code> functions may modify some or all of the levels.<p>
  613.    *      After the <code>nsBidi</code> object is reused or destroyed, the caller
  614.    *      must take care of the deallocation of the <code>aEmbeddingLevels</code> array.<p>
  615.    *      <strong>The <code>aEmbeddingLevels</code> array must be
  616.    *      at least <code>aLength</code> long.</strong>
  617.    */
  618.   nsresult SetPara(const PRUnichar *aText, PRInt32 aLength, nsBidiLevel aParaLevel, nsBidiLevel *aEmbeddingLevels);
  619.  
  620. #ifdef FULL_BIDI_ENGINE
  621.   /**
  622.    * <code>SetLine</code> sets an <code>nsBidi</code> to
  623.    * contain the reordering information, especially the resolved levels,
  624.    * for all the characters in a line of text. This line of text is
  625.    * specified by referring to an <code>nsBidi</code> object representing
  626.    * this information for a paragraph of text, and by specifying
  627.    * a range of indexes in this paragraph.<p>
  628.    * In the new line object, the indexes will range from 0 to <code>aLimit-aStart</code>.<p>
  629.    *
  630.    * This is used after calling <code>SetPara</code>
  631.    * for a paragraph, and after line-breaking on that paragraph.
  632.    * It is not necessary if the paragraph is treated as a single line.<p>
  633.    *
  634.    * After line-breaking, rules (L1) and (L2) for the treatment of
  635.    * trailing WS and for reordering are performed on
  636.    * an <code>nsBidi</code> object that represents a line.<p>
  637.    *
  638.    * <strong>Important:</strong> the line <code>nsBidi</code> object shares data with
  639.    * <code>aParaBidi</code>.
  640.    * You must destroy or reuse this object before <code>aParaBidi</code>.
  641.    * In other words, you must destroy or reuse the <code>nsBidi</code> object for a line
  642.    * before the object for its parent paragraph.
  643.    *
  644.    * @param aParaBidi is the parent paragraph object.
  645.    *
  646.    * @param aStart is the line's first index into the paragraph text.
  647.    *
  648.    * @param aLimit is just behind the line's last index into the paragraph text
  649.    *      (its last index +1).<br>
  650.    *      It must be <code>0<=aStart<=aLimit<=</code>paragraph length.
  651.    *
  652.    * @see SetPara
  653.    */
  654.   nsresult SetLine(nsIBidi* aParaBidi, PRInt32 aStart, PRInt32 aLimit);  
  655.  
  656.   /**
  657.    * Get the directionality of the text.
  658.    *
  659.    * @param aDirection receives a <code>NSBIDI_XXX</code> value that indicates if the entire text
  660.    *       represented by this object is unidirectional,
  661.    *       and which direction, or if it is mixed-directional.
  662.    *
  663.    * @see nsBidiDirection
  664.    */
  665.   nsresult GetDirection(nsBidiDirection* aDirection);
  666.  
  667.   /**
  668.    * Get the length of the text.
  669.    *
  670.    * @param aLength receives the length of the text that the nsBidi object was created for.
  671.    */
  672.   nsresult GetLength(PRInt32* aLength);
  673.  
  674.   /**
  675.    * Get the paragraph level of the text.
  676.    *
  677.    * @param aParaLevel receives a <code>NSBIDI_XXX</code> value indicating the paragraph level
  678.    *
  679.    * @see nsBidiLevel
  680.    */
  681.   nsresult GetParaLevel(nsBidiLevel* aParaLevel);
  682.  
  683.   /**
  684.    * Get the level for one character.
  685.    *
  686.    * @param aCharIndex the index of a character.
  687.    *
  688.    * @param aLevel receives the level for the character at aCharIndex.
  689.    *
  690.    * @see nsBidiLevel
  691.    */
  692.   nsresult GetLevelAt(PRInt32 aCharIndex,  nsBidiLevel* aLevel);
  693.  
  694.   /**
  695.    * Get an array of levels for each character.<p>
  696.    *
  697.    * Note that this function may allocate memory under some
  698.    * circumstances, unlike <code>GetLevelAt</code>.
  699.    *
  700.    * @param aLevels receives a pointer to the levels array for the text,
  701.    *       or <code>NULL</code> if an error occurs.
  702.    *
  703.    * @see nsBidiLevel
  704.    */
  705.   nsresult GetLevels(nsBidiLevel** aLevels);
  706. #endif // FULL_BIDI_ENGINE
  707.   /**
  708.    * Get the bidirectional type for one character.
  709.    *
  710.    * @param aCharIndex the index of a character.
  711.    *
  712.    * @param aType receives the bidirectional type of the character at aCharIndex.
  713.    */
  714.   nsresult GetCharTypeAt(PRInt32 aCharIndex,  nsCharType* aType);
  715.  
  716.   /**
  717.    * Get a logical run.
  718.    * This function returns information about a run and is used
  719.    * to retrieve runs in logical order.<p>
  720.    * This is especially useful for line-breaking on a paragraph.
  721.    *
  722.    * @param aLogicalStart is the first character of the run.
  723.    *
  724.    * @param aLogicalLimit will receive the limit of the run.
  725.    *      The l-value that you point to here may be the
  726.    *      same expression (variable) as the one for
  727.    *      <code>aLogicalStart</code>.
  728.    *      This pointer can be <code>NULL</code> if this
  729.    *      value is not necessary.
  730.    *
  731.    * @param aLevel will receive the level of the run.
  732.    *      This pointer can be <code>NULL</code> if this
  733.    *      value is not necessary.
  734.    */
  735.   nsresult GetLogicalRun(PRInt32 aLogicalStart, PRInt32* aLogicalLimit, nsBidiLevel* aLevel);
  736.  
  737.   /**
  738.    * Get the number of runs.
  739.    * This function may invoke the actual reordering on the
  740.    * <code>nsBidi</code> object, after <code>SetPara</code>
  741.    * may have resolved only the levels of the text. Therefore,
  742.    * <code>CountRuns</code> may have to allocate memory,
  743.    * and may fail doing so.
  744.    *
  745.    * @param aRunCount will receive the number of runs.
  746.    */
  747.   nsresult CountRuns(PRInt32* aRunCount);
  748.  
  749.   /**
  750.    * Get one run's logical start, length, and directionality,
  751.    * which can be 0 for LTR or 1 for RTL.
  752.    * In an RTL run, the character at the logical start is
  753.    * visually on the right of the displayed run.
  754.    * The length is the number of characters in the run.<p>
  755.    * <code>CountRuns</code> should be called
  756.    * before the runs are retrieved.
  757.    *
  758.    * @param aRunIndex is the number of the run in visual order, in the
  759.    *      range <code>[0..CountRuns-1]</code>.
  760.    *
  761.    * @param aLogicalStart is the first logical character index in the text.
  762.    *      The pointer may be <code>NULL</code> if this index is not needed.
  763.    *
  764.    * @param aLength is the number of characters (at least one) in the run.
  765.    *      The pointer may be <code>NULL</code> if this is not needed.
  766.    *
  767.    * @param aDirection will receive the directionality of the run,
  768.    *       <code>NSBIDI_LTR==0</code> or <code>NSBIDI_RTL==1</code>,
  769.    *       never <code>NSBIDI_MIXED</code>.
  770.    *
  771.    * @see CountRuns<p>
  772.    *
  773.    * Example:
  774.    * @code
  775.    *  PRInt32 i, count, logicalStart, visualIndex=0, length;
  776.    *  nsBidiDirection dir;
  777.    *  pBidi->CountRuns(&count);
  778.    *  for(i=0; i<count; ++i) {
  779.    *    pBidi->GetVisualRun(i, &logicalStart, &length, &dir);
  780.    *    if(NSBIDI_LTR==dir) {
  781.    *      do { // LTR
  782.    *        show_char(text[logicalStart++], visualIndex++);
  783.    *      } while(--length>0);
  784.    *    } else {
  785.    *      logicalStart+=length;  // logicalLimit
  786.    *      do { // RTL
  787.    *        show_char(text[--logicalStart], visualIndex++);
  788.    *      } while(--length>0);
  789.    *    }
  790.    *  }
  791.    * @endcode
  792.    *
  793.    * Note that in right-to-left runs, code like this places
  794.    * modifier letters before base characters and second surrogates
  795.    * before first ones.
  796.    */
  797.   nsresult GetVisualRun(PRInt32 aRunIndex, PRInt32* aLogicalStart, PRInt32* aLength, nsBidiDirection* aDirection);
  798.  
  799. #ifdef FULL_BIDI_ENGINE
  800.   /**
  801.    * Get the visual position from a logical text position.
  802.    * If such a mapping is used many times on the same
  803.    * <code>nsBidi</code> object, then calling
  804.    * <code>GetLogicalMap</code> is more efficient.<p>
  805.    *
  806.    * Note that in right-to-left runs, this mapping places
  807.    * modifier letters before base characters and second surrogates
  808.    * before first ones.
  809.    *
  810.    * @param aLogicalIndex is the index of a character in the text.
  811.    *
  812.    * @param aVisualIndex will receive the visual position of this character.
  813.    *
  814.    * @see GetLogicalMap
  815.    * @see GetLogicalIndex
  816.    */
  817.   nsresult GetVisualIndex(PRInt32 aLogicalIndex, PRInt32* aVisualIndex);
  818.  
  819.   /**
  820.    * Get the logical text position from a visual position.
  821.    * If such a mapping is used many times on the same
  822.    * <code>nsBidi</code> object, then calling
  823.    * <code>GetVisualMap</code> is more efficient.<p>
  824.    *
  825.    * This is the inverse function to <code>GetVisualIndex</code>.
  826.    *
  827.    * @param aVisualIndex is the visual position of a character.
  828.    *
  829.    * @param aLogicalIndex will receive the index of this character in the text.
  830.    *
  831.    * @see GetVisualMap
  832.    * @see GetVisualIndex
  833.    */
  834.   nsresult GetLogicalIndex(PRInt32 aVisualIndex, PRInt32* aLogicalIndex);
  835.  
  836.   /**
  837.    * Get a logical-to-visual index map (array) for the characters in the nsBidi
  838.    * (paragraph or line) object.
  839.    *
  840.    * @param aIndexMap is a pointer to an array of <code>GetLength</code>
  841.    *      indexes which will reflect the reordering of the characters.
  842.    *      The array does not need to be initialized.<p>
  843.    *      The index map will result in <code>aIndexMap[aLogicalIndex]==aVisualIndex</code>.<p>
  844.    *
  845.    * @see GetVisualMap
  846.    * @see GetVisualIndex
  847.    */
  848.   nsresult GetLogicalMap(PRInt32 *aIndexMap);
  849.  
  850.   /**
  851.    * Get a visual-to-logical index map (array) for the characters in the nsBidi
  852.    * (paragraph or line) object.
  853.    *
  854.    * @param aIndexMap is a pointer to an array of <code>GetLength</code>
  855.    *      indexes which will reflect the reordering of the characters.
  856.    *      The array does not need to be initialized.<p>
  857.    *      The index map will result in <code>aIndexMap[aVisualIndex]==aLogicalIndex</code>.<p>
  858.    *
  859.    * @see GetLogicalMap
  860.    * @see GetLogicalIndex
  861.    */
  862.   nsresult GetVisualMap(PRInt32 *aIndexMap);
  863.  
  864.   /**
  865.    * This is a convenience function that does not use a nsBidi object.
  866.    * It is intended to be used for when an application has determined the levels
  867.    * of objects (character sequences) and just needs to have them reordered (L2).
  868.    * This is equivalent to using <code>GetLogicalMap</code> on a
  869.    * <code>nsBidi</code> object.
  870.    *
  871.    * @param aLevels is an array with <code>aLength</code> levels that have been determined by
  872.    *      the application.
  873.    *
  874.    * @param aLength is the number of levels in the array, or, semantically,
  875.    *      the number of objects to be reordered.
  876.    *      It must be <code>aLength>0</code>.
  877.    *
  878.    * @param aIndexMap is a pointer to an array of <code>aLength</code>
  879.    *      indexes which will reflect the reordering of the characters.
  880.    *      The array does not need to be initialized.<p>
  881.    *      The index map will result in <code>aIndexMap[aLogicalIndex]==aVisualIndex</code>.
  882.    */
  883.   nsresult ReorderLogical(const nsBidiLevel *aLevels, PRInt32 aLength, PRInt32 *aIndexMap);
  884. #endif // FULL_BIDI_ENGINE
  885.   /**
  886.    * This is a convenience function that does not use a nsBidi object.
  887.    * It is intended to be used for when an application has determined the levels
  888.    * of objects (character sequences) and just needs to have them reordered (L2).
  889.    * This is equivalent to using <code>GetVisualMap</code> on a
  890.    * <code>nsBidi</code> object.
  891.    *
  892.    * @param aLevels is an array with <code>aLength</code> levels that have been determined by
  893.    *      the application.
  894.    *
  895.    * @param aLength is the number of levels in the array, or, semantically,
  896.    *      the number of objects to be reordered.
  897.    *      It must be <code>aLength>0</code>.
  898.    *
  899.    * @param aIndexMap is a pointer to an array of <code>aLength</code>
  900.    *      indexes which will reflect the reordering of the characters.
  901.    *      The array does not need to be initialized.<p>
  902.    *      The index map will result in <code>aIndexMap[aVisualIndex]==aLogicalIndex</code>.
  903.    */
  904.   nsresult ReorderVisual(const nsBidiLevel *aLevels, PRInt32 aLength, PRInt32 *aIndexMap);
  905.  
  906. #ifdef FULL_BIDI_ENGINE
  907.   /**
  908.    * Invert an index map.
  909.    * The one-to-one index mapping of the first map is inverted and written to
  910.    * the second one.
  911.    *
  912.    * @param aSrcMap is an array with <code>aLength</code> indexes
  913.    *      which define the original mapping.
  914.    *
  915.    * @param aDestMap is an array with <code>aLength</code> indexes
  916.    *      which will be filled with the inverse mapping.
  917.    *
  918.    * @param aLength is the length of each array.
  919.    */
  920.   nsresult InvertMap(const PRInt32 *aSrcMap, PRInt32 *aDestMap, PRInt32 aLength);
  921. #endif // FULL_BIDI_ENGINE
  922.   /**
  923.    * Reverse a Right-To-Left run of Unicode text.
  924.    *
  925.    * This function preserves the integrity of characters with multiple
  926.    * code units and (optionally) modifier letters.
  927.    * Characters can be replaced by mirror-image characters
  928.    * in the destination buffer. Note that "real" mirroring has
  929.    * to be done in a rendering engine by glyph selection
  930.    * and that for many "mirrored" characters there are no
  931.    * Unicode characters as mirror-image equivalents.
  932.    * There are also options to insert or remove Bidi control
  933.    * characters; see the description of the <code>aDestSize</code>
  934.    * and <code>aOptions</code> parameters and of the option bit flags.
  935.    *
  936.    * Since no Bidi controls are inserted here, this function will never
  937.    * write more than <code>aSrcLength</code> characters to <code>aDest</code>.
  938.    *
  939.    * @param aSrc A pointer to the RTL run text.
  940.    *
  941.    * @param aSrcLength The length of the RTL run.
  942.    *                 If the <code>NSBIDI_REMOVE_BIDI_CONTROLS</code> option
  943.    *                 is set, then the destination length may be less than
  944.    *                 <code>aSrcLength</code>.
  945.    *                 If this option is not set, then the destination length
  946.    *                 will be exactly <code>aSrcLength</code>.
  947.    *
  948.    * @param aDest A pointer to where the reordered text is to be copied.
  949.    *             <code>aSrc[aSrcLength]</code> and <code>aDest[aSrcLength]</code>
  950.    *             must not overlap.
  951.    *
  952.    * @param aOptions A bit set of options for the reordering that control
  953.    *                how the reordered text is written.
  954.    *
  955.    * @param aDestSize will receive the number of characters that were written to <code>aDest</code>.
  956.    */
  957.   nsresult WriteReverse(const PRUnichar *aSrc, PRInt32 aSrcLength, PRUnichar *aDest, PRUint16 aOptions, PRInt32 *aDestSize);
  958.  
  959.   /**
  960.    * Give a UTF-32 codepoint
  961.    * return PR_TRUE if the codepoint is a Bidi control character (LRE, RLE, PDF, LRO, RLO, LRM, RLM)
  962.    * return PR_FALSE, otherwise
  963.    */
  964.   PRBool IsBidiControl(PRUint32 aChar);
  965.  
  966. protected:
  967.   /** length of the current text */
  968.   PRInt32 mLength;
  969.  
  970.   /** memory sizes in bytes */
  971.   PRSize mDirPropsSize, mLevelsSize, mRunsSize;
  972.  
  973.   /** allocated memory */
  974.   DirProp* mDirPropsMemory;
  975.   nsBidiLevel* mLevelsMemory;
  976.   Run* mRunsMemory;
  977.  
  978.   /** indicators for whether memory may be allocated after construction */
  979.   PRBool mMayAllocateText, mMayAllocateRuns;
  980.  
  981.   const DirProp* mDirProps;
  982.   nsBidiLevel* mLevels;
  983.  
  984.   /** the paragraph level */
  985.   nsBidiLevel mParaLevel;
  986.  
  987.   /** flags is a bit set for which directional properties are in the text */
  988.   Flags mFlags;
  989.  
  990.   /** the overall paragraph or line directionality - see nsBidiDirection */
  991.   nsBidiDirection mDirection;
  992.  
  993.   /** characters after trailingWSStart are WS and are */
  994.   /* implicitly at the paraLevel (rule (L1)) - levels may not reflect that */
  995.   PRInt32 mTrailingWSStart;
  996.  
  997.   /** fields for line reordering */
  998.   PRInt32 mRunCount;     /* ==-1: runs not set up yet */
  999.   Run* mRuns;
  1000.  
  1001.   /** for non-mixed text, we only need a tiny array of runs (no malloc()) */
  1002.   Run mSimpleRuns[1];
  1003.  
  1004. private:
  1005.  
  1006.   void Init();
  1007.  
  1008.   PRBool GetMemory(void **aMemory, PRSize* aSize, PRBool aMayAllocate, PRSize aSizeNeeded);
  1009.  
  1010.   void Free();
  1011.  
  1012.   void GetDirProps(const PRUnichar *aText);
  1013.  
  1014.   nsBidiDirection ResolveExplicitLevels();
  1015.  
  1016.   nsresult CheckExplicitLevels(nsBidiDirection *aDirection);
  1017.  
  1018.   nsBidiDirection DirectionFromFlags(Flags aFlags);
  1019.  
  1020.   void ResolveImplicitLevels(PRInt32 aStart, PRInt32 aLimit, DirProp aSOR, DirProp aEOR);
  1021.  
  1022.   void AdjustWSLevels();
  1023.  
  1024.   void SetTrailingWSStart();
  1025.  
  1026.   PRBool GetRuns();
  1027.  
  1028.   void GetSingleRun(nsBidiLevel aLevel);
  1029.  
  1030.   void ReorderLine(nsBidiLevel aMinLevel, nsBidiLevel aMaxLevel);
  1031.  
  1032.   PRBool PrepareReorder(const nsBidiLevel *aLevels, PRInt32 aLength, PRInt32 *aIndexMap, nsBidiLevel *aMinLevel, nsBidiLevel *aMaxLevel);
  1033.   /**
  1034.    * Give a UTF-32 codepoint, return an eBidiCategory
  1035.    */
  1036.   eBidiCategory GetBidiCategory(PRUint32 aChar);
  1037.  
  1038.   /**
  1039.    * Give a UTF-32 codepoint and an eBidiCategory, 
  1040.    * return PR_TRUE if the codepoint is in that category, 
  1041.    * return PR_FALSE, otherwise
  1042.    */
  1043.   PRBool IsBidiCategory(PRUint32 aChar, eBidiCategory aBidiCategory);
  1044.  
  1045.   /**
  1046.    * Give a UTF-32 codepoint, return a nsCharType (compatible with ICU)
  1047.    */
  1048.   nsCharType GetCharType(PRUint32 aChar);
  1049.  
  1050.   /**
  1051.    * Give a Unicode character, return the symmetric equivalent
  1052.    */
  1053.   PRUint32 SymmSwap(PRUint32 aChar);
  1054.  
  1055.   PRInt32 doWriteReverse(const PRUnichar *src, PRInt32 srcLength,
  1056.                          PRUnichar *dest, PRUint16 options);
  1057.  
  1058. };
  1059.  
  1060. #endif // _nsBidi_h_
  1061.